package yxy.game.pm2.active.module;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import jodd.time.TimeUtil;
import org.joda.time.DateTime;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.bean.actfirstcharge;
import yxy.game.pm2.Result;
import yxy.game.pm2.active.ActiveUtil;
import yxy.game.pm2.active.Global;
import yxy.game.pm2.active.module.actcontrol.activeControl;
import yxy.game.pm2.active.module.actdata.ActDataCenter;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.AreaModule;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.timeline.Timeline;
import yxy.game.pm2.message.PackageMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 类型号 2
 *
 * @author Dell
 */
public class ActiveModule_每日首充 extends PlayerModule {

    //缓存过期时间
    private static long expire = 1;
    private static TimeUnit expireTimeUnit = TimeUnit.DAYS;

    public static final int acttype = 2;

    private DateTime updatetime; // 更新时间
    private int payexp; // 今日充值经验
    private JSONObject needtopupexp; // 需要充值多少才可以领奖
    private ArrayList<Integer> cangetidlist; // 可以领取的奖励组id
    private ArrayList<Integer> getidlist; // 已经领取的奖励组id

    public DateTime getUpdatetime() {
        return updatetime;
    }

    public void setUpdatetime(DateTime updatetime) {
        this.updatetime = updatetime;
    }

    public int getPayexp() {
        return payexp;
    }

    public void setPayexp(int payexp) {
        this.payexp = payexp;
    }

    public JSONObject getNeedtopupexp() {
        return needtopupexp;
    }

    public void setNeedtopupexp(JSONObject needtopupexp) {
        this.needtopupexp = needtopupexp;
    }

    public ArrayList<Integer> getCangetidlist() {
        return cangetidlist;
    }

    public void setCangetidlist(ArrayList<Integer> cangetidlist) {
        this.cangetidlist = cangetidlist;
    }

    public ArrayList<Integer> getGetidlist() {
        return getidlist;
    }

    public void setGetidlist(ArrayList<Integer> getidlist) {
        this.getidlist = getidlist;
    }

    // fun======================================================================

    /**
     * 充值处理
     *
     * @param addtopupexp
     */
    public void addtopupexp(int addtopupexp) {

        int sumtopupexp = getPayexp() + addtopupexp;
        JSONObject needtopupexp = getneedtopupexp(sumtopupexp, getNeedtopupexp());

        Map<String, actfirstcharge> actfcmap = ActDataCenter.getAllData(actfirstcharge.class, getPlayerCode());
        for (String key : actfcmap.keySet()) {
            actfirstcharge afc = actfcmap.get(key);

            int condtion = afc.getCondition();
            if (sumtopupexp < condtion) {
                continue;
            }

            int afcid = afc.getId();
            if (!getGetidlist().contains(afcid)) {
                if (!getCangetidlist().contains(afcid)) {
                    getCangetidlist().add(afcid);
                }
            }
        }

        setPayexp(sumtopupexp);
        setNeedtopupexp(needtopupexp);

        this.set();
    }

    /**
     * 是否能领取奖励
     *
     * @param rewardid 奖励组id
     * @return
     */
    public Result getstateofreward(int rewardid) {
        if (!getCangetidlist().contains(rewardid)) {
            return Result.ActCannotGet;
        }
        if (getGetidlist().contains(rewardid)) {
            return Result.ActHadGet;
        }
        return Result.Success;
    }

    /**
     * 领取奖励
     *
     * @param rewardid
     * @return
     */
    public JSONArray handlegetreward(int rewardid) {

        getGetidlist().add(rewardid);
        getCangetidlist().remove((Object) rewardid);
        setNeedtopupexp(getneedtopupexp(getPayexp(), getNeedtopupexp()));
        this.set();

        JSONArray arr = new JSONArray();

        // 下发奖励
        actfirstcharge asc = ActDataCenter.getData(rewardid, actfirstcharge.class, getPlayerCode());
        for (int i = 0; i < asc.getRewardtype().length; i++) {
            int type = asc.getRewardtype()[i];
            int dataid = asc.getRewardid()[i];
            int number = asc.getRewardnum()[i];

            Currency cur = Currency.create(CurrencyType.forNumber(type), dataid, number);
            PackageMessage.Item.Builder builder = PackageMessage.Item.newBuilder();
            builder.setType(cur.getType().getNumber());
            builder.setDataId(cur.getDataId());
            builder.setNumber(cur.getNumber());
            arr.add(builder.build());

            CurrencyHandle ch = new CurrencyHandle();
            ch.addCurrency(getPlayerCode(), CCReason.活动_每日首充, cur);
        }

        return arr;
    }

    /**
     * 创建数据
     */
    static private ActiveModule_每日首充 create(String playerCode, activeControl sai, int sid) {

        int opentype = sai.getOpentype(); // 0.按照开始时间 1.按照开服时间
        DateTime startTime = sai.getStarttime(); // 活动开始时间
        if (opentype == 1) {
            ServerBean sb = ServerBean.get(sid);
            startTime = sb.getStarttime();
        }

        DateTime endTime = sai.getEndtime(); // 活动结束时间/本轮结束时间
        int cycle = sai.getCircledays(); // 永久持续填-1 填写数字为活动持续对应天数
        if (cycle > -1) {
            long mills = startTime.getMillis() + TimeUtil.MILLIS_IN_DAY * cycle;
            endTime = new DateTime(mills);
        }

        long circleTime = endTime.getMillis() - startTime.getMillis();
        int round = 0;

        Timeline tl = new Timeline();
        tl.setStartTime(startTime);
        tl.setEndTime(endTime);
        tl.setCircleTime(circleTime);
        tl.setRound(round);

        ActiveModule_每日首充 am = new ActiveModule_每日首充();
        am.setPlayerCode(playerCode);
        am.setPayexp(0);
        am.setNeedtopupexp(am.getneedtopupexp(0, new JSONObject()));
        am.setGetidlist(new ArrayList<Integer>());
        am.setCangetidlist(new ArrayList<Integer>());
        am.setTimeline(tl);
        am.setUpdatetime(new DateTime(0));

        am.set();
        return am;
    }

    /**
     * 获取领奖所需充值经验
     *
     * @param topupexp
     * @return
     */
    public JSONObject getneedtopupexp(int topupexp, JSONObject json) {

        Map<String, actfirstcharge> actfcmap = ActDataCenter.getAllData(actfirstcharge.class, getPlayerCode());
        for (String key : actfcmap.keySet()) {
            actfirstcharge afc = actfcmap.get(key);

            int condition = afc.getCondition();
            int needtopupexp = condition > topupexp ? condition - topupexp : 0; // 需要充值数
            json.put(String.valueOf(afc.getId()), needtopupexp);
        }
        return json;
    }

    private void update() {

//		PlayerBean pb = PlayerBean.get(getPlayerCode());
//		int sid = pb.getServerId();
//		ServerBean sb = ServerBean.get(sid);
//		int areaid = sb.getAreaId();
        AreaBean ab = AreaModule.area(getPlayerCode());
        activeControl sai = activeControl.getAreaOneActionInfo(String.valueOf(ab.getAreaId()), String.valueOf(acttype));
        if (sai == null) {
            return;
        }

        if (sai != null) {

            if (sai.getCircledays() != -1) {
                // 循环活动
                sai.running();
                int sairound = sai.getTimeline().getRound();
                int round = getTimeline().getRound();
                if (sairound > round) {
                    Timeline tl = sai.getTimeline();
                    setTimeline(tl);
                    setPayexp(0);
                    setNeedtopupexp(getneedtopupexp(0, new JSONObject()));
                    setGetidlist(new ArrayList<Integer>());
                    setCangetidlist(new ArrayList<Integer>());
                    setUpdatetime(DateTime.now());
                    this.set();
                }
            } else {
                // 不循环
                DateTime saistart = sai.getStarttime();
                DateTime saiend = sai.getEndtime();
                DateTime end = getTimeline().getEndTime();

                if (saistart.getMillis() > end.getMillis()) {
                    Timeline tl = new Timeline();
                    tl.setStartTime(saistart);
                    tl.setEndTime(saiend);
                    tl.setRound(0);
                    tl.setCircleTime(saiend.getMillis() - saistart.getMillis());
                    setTimeline(tl);
                    setPayexp(0);
                    setNeedtopupexp(getneedtopupexp(0, new JSONObject()));
                    setGetidlist(new ArrayList<Integer>());
                    setCangetidlist(new ArrayList<Integer>());
                    setUpdatetime(DateTime.now());
                    this.set();
                }
            }

        }

        DateTime old = getUpdatetime();
        DateTime now = DateTime.now();

        int days = ActiveUtil.days(old, now);
        if (days >= 1) {
            setPayexp(0);
            setNeedtopupexp(getneedtopupexp(0, new JSONObject()));
            setGetidlist(new ArrayList<Integer>());
            setCangetidlist(new ArrayList<Integer>());
            setUpdatetime(DateTime.now());
            this.set();
        }
    }

    // redis --------------------------------------------

    private static String key(String pcode) {
        return String.format("PLAYER:%s:ACTIVE:%S", pcode, acttype);
    }

    public void set() {
        try {
            String key1 = key(getPlayerCode());
            setv(key1, this, Global.expire, Global.expireTimeUnit);

            check();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static public ActiveModule_每日首充 get(String playerCode, Boolean isNewPlayer) {
        try {

            ActiveModule_每日首充 module = getv(key(playerCode));
            //新用户不需要去查数据库
            if (module == null && !isNewPlayer) {
                module = MySQLCacheDAO.getV(key(playerCode), ActiveModule_每日首充.class);
                if (module != null) {
                    module.set();
                }//同步到redis
            }

            if (module == null) {
                PlayerBean pb = PlayerBean.get(playerCode);
                int sid = pb.getServerId();
                ServerBean sb = ServerBean.get(sid);
                int areaid = sb.getAreaId();
                activeControl sai = activeControl.get(String.valueOf(areaid), String.valueOf(acttype));
                if (sai != null) {
                    module = create(playerCode, sai, sid);
                }
            }
            if (module == null) {
                return null;
            }

            module.update();
            module.check();

            return module;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查看是否有可领取奖励 控制红点
     */
    public void check() {
        ArrayList<Integer> cangetlist = getCangetidlist();
        ArrayList<Integer> hadgetlist = getGetidlist();

        boolean canget = false;
        for (int id : cangetlist) {
            if (!hadgetlist.contains(id)) {
                canget = true;
            }
        }
        if (!running()) {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.关闭);
            new TipHandle().updateTip(getPlayerCode(), TipType.活动_每日首充奖励, false);
            return;
        } else {
            Map<String, actfirstcharge> actfcmap = ActDataCenter.getAllData(actfirstcharge.class, getPlayerCode());
            int size = actfcmap.size();
            if (hadgetlist.size() == size) {
                new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.领完了);
            } else {
                new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.开启);
            }
        }

        if (canget) {
            new TipHandle().updateTip(getPlayerCode(), TipType.活动_每日首充奖励, true);
        } else {
            new TipHandle().updateTip(getPlayerCode(), TipType.活动_每日首充奖励, false);
        }
    }

    //存储到数据库的方法
    public static void saveToDB(String playerCode) {
        try {
            String key = key(playerCode);
            if (touchBucket(key).isExists()) {
                ActiveModule_每日首充 activeModule_每日首充 = getv(key(playerCode));
                MySQLCacheDAO.setV(key, activeModule_每日首充);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //从redis移走数据的操作
    public static void removeAllFromRedis(String playerCode) {
        try {
            touchBucket(key(playerCode)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    // lock==========================================================================

    @Override
    public String lockKey() {
        return String.format("lock:%s", key(getPlayerCode()));
    }
}
